package org.gitman.agent.platform;

import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import com.mxgraph.analysis.mxConstantCostFunction;
import com.mxgraph.analysis.mxGraphAnalysis;
import com.mxgraph.analysis.mxICostFunction;
import com.mxgraph.model.mxICell;
import com.mxgraph.util.mxConstants;
import com.mxgraph.view.mxGraph;

public class AgentUtils {
	
	public static String defaultColor = "#C3D9FF";
	
	/**
	 * this method returns list of childs of the given vertex. If reachable is set to true
	 * It takes under considoration only edges outgoing from given vertex. 
	 * @param parent
	 * @param graph
	 * @param reachable
	 * @return
	 */
	public static List<mxICell> getAllChilds(mxICell parent, mxGraph graph, boolean reachable){
		final List<mxICell> childs = new LinkedList<mxICell>();		
//		int count = parent.getEdgeCount();
//		for(int i = 0;i<count;i++){
//			mxICell edge = parent.getEdgeAt(i);
//			mxICell end = edge.getTerminal(false);
//			if(!end.equals(parent)){
//				if(!reachable || end.getValue() == null){
//					childs.add(end);
//				}
//			}
//		}
		
		for(Object o : graph.getOutgoingEdges(parent)){
			mxICell end = ((mxICell) o).getTerminal(false);
			if(!end.equals(parent)){
				//this maybe is wrong
				if(!reachable || !AgentUtils.isCellOcupied(end, graph)){
					childs.add(end);
				}
			}
		}
		return childs;
	}

	/**
	 * this method returns shortes path between two vertecies. If size of the return table is 0 
	 * then vertex to is not reachable from vertex from. On the path there are vertices
	 * with end point but without starting point
	 * @param graph
	 * @param from
	 * @param to
	 * @return
	 */
	public static mxICell [] getShortestPath(mxGraph graph, mxICell from, mxICell to){
		mxICostFunction cf = new mxConstantCostFunction(1); 
		Object[] v = graph.getChildVertices(graph.getDefaultParent()); 
		mxGraphAnalysis mga = mxGraphAnalysis.getInstance();
		Object[] path = mga.getShortestPath(graph, from, to, cf, v.length, true);
		mxICell [] vPath = new mxICell[path.length];
		for(int i =0;i<path.length;i++){
			vPath[i] = ((mxICell) path[i]).getTerminal(false);
		}
		return vPath;
	}

	/**
	 * this method returns true if given cell is occupied by agent (its fill color is not null)
	 * @param cell
	 * @param graph
	 * @return
	 */
	public static boolean isCellOcupied(mxICell cell, mxGraph graph){
		Map<String, Object> cellStyle = graph.getCellStyle(cell);
		Object color = cellStyle.get(mxConstants.STYLE_FILLCOLOR);
		if(color == null || color.equals(AgentUtils.defaultColor)){
			return false;
		}else{
			return true;
		}
	}
}
